package com.motu.monstercity.server.game.logic;

import com.motu.monstercity.module.common.utility.Constant;
import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.Common.PBWeaponAtt;
import com.motu.monstercity.protocol.CsGameSystem;
import com.motu.monstercity.protocol.CsGameSystem.CSGameSystemRedPointResponse;
import com.motu.monstercity.server.game.base.AllParam;
import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.bag.ItemId;
import com.motu.monstercity.server.game.commondata.mail.MailConstant;
import com.motu.monstercity.server.game.commondata.maintask.MainTaskConstant;
import com.motu.monstercity.server.game.commondata.maintask.TaskAchieve;
import com.motu.monstercity.server.game.commondata.partner.*;
import com.motu.monstercity.server.game.commondata.skill.Skill;
import com.motu.monstercity.server.game.commondata.skill.SkillConstant;
import com.motu.monstercity.server.game.commondata.skill.SkillEffectType;
import com.motu.monstercity.server.game.log.LogType;
import com.motu.monstercity.server.game.log.MotuLogManager;
import com.motu.monstercity.server.game.userdata.*;
import com.motu.vertx.module.utility.model.EntityManager;
import com.motu.vertx.module.utility.model.Model;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.json.JsonArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class PartnerManager extends PartnerUserData {
    private static Logger logger = LoggerFactory.getLogger(PartnerManager.class);

    // 初始化下发伙伴模块的用户数据 干员列表,重算战力时需要用到
    public static void loadInitPartnerUserData(PBUserData.Builder pbUserData, UserInfo userInfo, List<UserPartner> partnerList, List<UserWeapon> weaponList) {
        long userId = userInfo.getId();
        for (UserPartner userPartner : getUserPartnerList(userId)) {
            PartnerMain partnerMain = getPartnerMain(userPartner.getPartnerId());
            if (partnerMain == null) {
                userPartner.delete();
            } else {
                partnerList.add(userPartner);
                ProtoDataUtils.updatePBUserData(pbUserData, userPartner, true);// 下发给客户端
            }
        }

        int totalNum = 0;// 属性生效的最高数量
        for (UserWeapon userWeapon : getUserWeaonList(userId)) {
            weaponList.add(userWeapon);
            ProtoDataUtils.updatePBUserData(pbUserData, userWeapon, true);
            totalNum += userWeapon.getAttActiveNum();
        }
        MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_171, totalNum);// 更新主线任务,成就,日常任务的进度
        RankActManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_171, totalNum);
        recountMainTaskTalentNum(pbUserData, userInfo, partnerList);
    }

    // 获得伙伴,干员, 只支持一次获得1个伙伴
    public static void addRewardPartner(UserInfo userInfo, int partnerId, long num, PBUserData.Builder pbUserData, Object... logParams) {
        long userId = userInfo.getId();
        PartnerMain partnerMain = getPartnerMain(partnerId);
        if (partnerMain == null) {
            return;
        }
        UserPartner userPartner = getUserPartner(userId, partnerId);
        if (userPartner != null) {
            return;// 已经获得过了
        }

        UserPower userPower = GameUser.getUserPower(userId);
        userPower.addPartnerId(partnerId);// 增加一个干员id 在干员重算战力之前，解锁干员有可能提升光环技能等级，影响干员战力

        userPartner = new UserPartner(userId, partnerId);
        userPartner.initSkillLevelData();// 技能的等级数据，策划改配置时，做相应修改

        int[] haloSkillList = partnerMain.takeSkillHaloList();// 光环技能会增加其他干员的战力
        if (haloSkillList != null && haloSkillList.length > 0) {
            for (int i=0;i<haloSkillList.length;i++) {
                int skillId = haloSkillList[i];
                int level = 1;// 初始技能都是1级
                Skill skill = SkillManager.getSkill(skillId);
                if (skill != null && skill.getEffectType() == SkillConstant.EFFECT_TYPE_45) {
                    JsonArray jsonArray = SkillManager.addSkillEffectArray(skill.getEffectParam(), skill.countTotalAdd(level), userPower.getPowerAddHaloPerArray());
                    userPower.putPowerAddHaloPer(jsonArray.toString());
                }
            }
        }

        List<UserSecretary> secretaryList = SecretaryManager.getUserSecrPatronList(userId, partnerId);// 有羁绊关系的秘书列表
        GameUser.initPartnerPower(userInfo, userPower, userPartner, secretaryList);// 刚获得干员时计算的战力
        userPartner.doCreate();

        if (haloSkillList != null && haloSkillList.length > 0) {
            JsonArray partnerIds = partnerMain.takeHaloPartnerIds();//  光环技能会影响到的其他干员, 某个性格的所有干员，和自己能组成光环的干员
            List<UserPartner> partnerList = PartnerManager.getUserPartnerList(userId, partnerIds);
            if (partnerList.size() > 0) {
                userPower.putPower(userPower.getPower() + userPartner.getTotalPower());// 先加这个干员的战力
                PartnerManager.batchUpdatePartnerPower(pbUserData, userInfo, userPower, partnerList);//  处理其他干员的战力增加
            } else {
                userPower.handlePowerChange(pbUserData, userInfo, userPower.getPower() + userPartner.getTotalPower());// 玩家的基础战力加上新干员的战力
            }
        } else {// 没有光环技能只增加该干员的战力
            userPower.handlePowerChange(pbUserData, userInfo, userPower.getPower() + userPartner.getTotalPower());// 玩家的基础战力加上新干员的战力
        }


        GameUser.updateUserShow(userInfo, null);// 更新用户展示数据
        List<Object> logParamsList = new ArrayList<>(Arrays.asList(logParams));
        logParamsList.add(partnerMain.getQuality()); // 武器需要记录品质
        Object[] newLogParamsList = logParamsList.toArray(new Object[0]);
        MotuLogManager.logItemIncome(userInfo, partnerId, 0, 0, 1, newLogParamsList);// 记录获得日志
        GameDataManager.unlockDecorateMain(pbUserData, userInfo, partnerId);// 获得干员或是秘书时 自动解锁头像框


        MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_142, getUserPartnerCount(userId));// 更新主线任务,成就,日常任务的进度
        MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_141, userPartner.takeTotalTalent());// 更新主线任务,成就,日常任务的进度
        RankActManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_142,  getUserPartnerCount(userId));
        RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_141, userPartner.takeTotalTalent());
        if (pbUserData != null) {
            ProtoDataUtils.updatePBUserData(pbUserData, userPartner, true);
        }
        int totalLevel = countTotalLevel(userId);// 总的等级数量
        MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_126, totalLevel);// 更新主线任务,成就,日常任务的进度
        RankActManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_126, totalLevel);
        EventManager.updateKeyMan(userId, partnerId);
    }

    // 获得武器
    public static void addRewardWeapon(UserInfo userInfo, int weaponId, long num, PBUserData.Builder pbUserData, Object... logParams) {
        long userId = userInfo.getId();
        WeaponMain weaponMain = getWeaponMain(weaponId);
        if (weaponMain == null) {
            return;
        }

        // 同种武器可以重复获得,分开记录,升级,装备等
        int weaponNum = countWeaponNum(userId);// 当前的武器数量
        int addNum = 0;// 实际获得的数量
        int mailNum = 0;// 发往邮件的武器数量
        for (int aa=0; aa<num; aa++) {
            if (weaponNum < AllParam.WEAPON_NUM_MAX) {
                JsonArray jsonArray = new JsonArray();
                for (int i=0; i<weaponMain.getSlotNum(); i++) {
                    jsonArray.add(takeRandomAtt(false));
                }
                UserWeapon userWeapon = new UserWeapon(userId, weaponId, weaponMain.getTalent(), jsonArray);
                userWeapon.doCreate();
                if (pbUserData != null) {
                    ProtoDataUtils.updatePBUserData(pbUserData, userWeapon);
                }
                weaponNum++;
                addNum++;
            } else {// 武器上限数量300,再次获得时则直接发往邮件
                mailNum++;
            }
        }

        // 武器上限数量300,再次获得时则直接发往邮件
        if (mailNum > 0) {
            List<RewardItem> mailItemList = new ArrayList<>();
            mailItemList.add(new RewardItem(weaponId, mailNum));
            MailManager.sendSystemMail(userId, MailConstant.WEAPON_ALREADY_REWARD_TITLE, MailConstant.WEAPON_ALREADY_REWARD_CONTENT, mailItemList, LogType.PARTNER_WEAPON_FULL);
        }

        // 武器图鉴
        if (addNum > 0) {
            UserWeaponBook userWeaponBook = getUserWeaponBook(userId, weaponId);
            if (userWeaponBook == null) {
                userWeaponBook = new UserWeaponBook();
                userWeaponBook.putUserId(userId);
                userWeaponBook.putWeaponId(weaponId);
                userWeaponBook.doCreate();
            }
            MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_148, getUserWeaponBookCount(userId));// 更新主线任务,成就,日常任务的进度
            RankActManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_148, getUserWeaponBookCount(userId));// 更新主线任务,成就,日常任务的进度
            List<Object> logParamsList = new ArrayList<>(Arrays.asList(logParams));
            logParamsList.add(weaponMain.getQuality()); // 武器需要记录品质
            Object[] newLogParamsList = logParamsList.toArray(new Object[0]);
            MotuLogManager.logItemIncome(userInfo, weaponId, 0, 0, addNum, newLogParamsList);// 记录获得日志
            MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_109, addNum);// 更新主线任务,成就,日常任务的进度
            RankActManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_109, addNum);// 更新主线任务,成就,日常任务的进度
        }
    }

    // 获得随机的属性加成type_value 如2_23,
    public static String takeRandomAtt(boolean isUserItem) {
        JsonArray typeList = new JsonArray().add(Constant.CHARACTER_TYPE_1).add(Constant.CHARACTER_TYPE_2).add(Constant.CHARACTER_TYPE_3).add(Constant.CHARACTER_TYPE_4).add(Constant.CHARACTER_TYPE_5);
        int type = typeList.getInteger(Tool.getRandom(0, typeList.size()-1));

        int value = 0;
        try {
            if (isUserItem) {
                value = CommonUtils.getRandom(AllParam.WEAPON_SKILL_CUSTOM_MODIFY_PARAM);// 数组序号从0开始
            } else {
                value = CommonUtils.getRandom(AllParam.WEAPON_SKILL_NORMAL_MODIFY_PARAM);
            }
        } catch (Exception e) {
            logger.error("###takeRandomAtt error: {}" + Tool.getException(e));
        }
        return type + "_" + value;// 4 表示4%
    }

    // 统计武器总的回收奖励
    public static List<RewardItem> takeRecycleReward(UserWeapon userWeapon) {
        WeaponMain weaponMain = PartnerManager.getWeaponMain(userWeapon.getWeaponId());
        List<RewardItem> rewardItems = CommonUtils.takeReawrdItemFromStr(weaponMain.getRecycleReward());// 基础奖励
        int addLevel = userWeapon.getLevel() - 1;// 升的级数
        if (addLevel > 0) {
            CommonUtils.addRewardItem(rewardItems, ItemId.WEAPON_LEVEL_UP, weaponMain.getUpgradeItem() * addLevel);// 累加升级的消耗
        }

        // 觉醒的总消耗
        for (int i=0; i<userWeapon.getAwakeNum(); i++) {
            WeaponAwake weaponAwake = getWeaponAwake(i);
            List<RewardItem> tmp = CommonUtils.takeReawrdItemFromStr(weaponAwake.getAwakeItem());
            CommonUtils.mergeItemList(rewardItems, tmp);
        }
        return rewardItems;
    }

    // 计算武器洗练消耗的金币数量
    public static long takeWeaponRefreshGold(int refreshNum) {
        // 武器消耗金币=(0.58*n)^4-(0.9*n)^3+9*n【n为次数】
        double aa = Math.pow(0.58 * refreshNum, 4);
        double bb = Math.pow(0.9 * refreshNum, 3);
        double result = aa - bb + 9 * refreshNum;
        return (long) Math.floor(result);

        //System.out.println(num + " == " + aa + "-" + bb + " = " + (aa-bb) + " 结果:" + (aa-bb+9*refreshNum));
        //return num;
    }

    public static PBWeaponAtt.Builder takePBWeaponAtt(String str) {
        if (!Tool.isEmpty(str)) {
            String[] tmp = str.split("_");
            PBWeaponAtt.Builder pbAtt = PBWeaponAtt.newBuilder();
            pbAtt.setType(Integer.parseInt(tmp[0]));
            pbAtt.setAddValue(Integer.parseInt(tmp[1]));
            return pbAtt;
        } else {
            return PBWeaponAtt.getDefaultInstance().toBuilder();
        }
    }

    //  获取所有干员的资质总和
    public static int takeAllTalent(long userId) {
        List<UserPartner> partnerList = getUserPartnerList(userId);
        int total = 0;
        for (UserPartner userPartner : partnerList) {
            total += userPartner.takeTotalTalent();
        }
        return total;
    }

    // 获取指定性格的干员列表
    public static List<UserPartner> takeUserPartnerList(long userId, UserPower userPower, int chatType) {
        List<UserPartner> result = new ArrayList<>();
        JsonArray jsonArray = userPower.takePartnerIds(chatType);// 已经获得的该性格的所有干员
        for (Model model : EntityManager.getEntityList(UserPartner.class, userId, jsonArray)) {
            UserPartner entity = (UserPartner) model;
            result.add(entity);
        }
        return result;
    }

    // 统计装备了武器的干员总数量
    public static int countPartnerWeapon(long userId)  {
        int total = 0;
        List<UserPartner> partnerList = getUserPartnerList(userId);
        for (UserPartner userPartner : partnerList) {
            if (userPartner.getWeaponDbid() > 0) {
                total++;
            }
        }
        return total;
    }

    // 统计武器的总等级
    public static int countWeaponLevel(long userId)  {
        int total = 0;
        List<UserWeapon> weaponList = getUserWeaonList(userId);
        for (UserWeapon userWeapon : weaponList) {
            total += userWeapon.getLevel();
        }
        return total;
    }

    // TASK_TYPE_107 = 107;// {1}名干员达到{0}级
    public static void updateMainTaskNum(PBUserData.Builder pbUserData, long userId) {
        List<UserPartner> partnerList = getUserPartnerList(userId);
        UserInfo userInfo = GameUser.getUserInfo(userId);
        for (TaskAchieve taskAchieve : MainTaskManager.getTaskAchieveMapByTaskType(MainTaskConstant.TASK_TYPE_107).values()) {
            int minLevel = taskAchieve.getParam();
            int num = countPartnerNumByLevel(partnerList, minLevel);// >level 的干员有多少人
            MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_107, num, minLevel);// 更新主线任务,成就,日常任务的进度
        }
//        ActDaysManager.updatePartnerTask(userInfo, pbUserData, partnerList); // 七天乐任务
        ActDaysManager.updateOuterTask(userInfo, pbUserData, MainTaskConstant.TASK_TYPE_107,  partnerList, PartnerManager::countPartnerNumByLevel); // 七天乐任务
        RankActManager.updateOuterTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_107,  partnerList, PartnerManager::countPartnerNumByLevel);
        ActConventionManager.updateOuterTask(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_107,  partnerList, PartnerManager::countPartnerNumByLevel);
    }

    // >level 的干员有多少人
    public static int countPartnerNumByLevel(List<UserPartner> partnerList, int minLevel) {
        int count = 0;
        for (UserPartner userPartner : partnerList) {
            if (userPartner.getLevel() >= minLevel) {
                count++;
            }
        }
        return count;
    }

    // 统计所有干员的总等级
    public static int countTotalLevel(long userId) {
        List<UserPartner> partnerList = getUserPartnerList(userId);
        int total = 0;
        for (UserPartner userPartner : partnerList) {
            total += userPartner.getLevel();
        }
        return total;
    }

    // TASK_TYPE_111 = 111;// {0}把武器资质达到{0}
    public static void updateWeaponTalentTaskNum(PBUserData.Builder pbUserData, UserInfo userInfo) {
        List<UserWeapon> weaponList = getUserWeaonList(userInfo.getId());
//        ActDaysManager.updateWeaponTask(userInfo, pbUserData, weaponList);
        ActDaysManager.updateOuterTask(userInfo, pbUserData, MainTaskConstant.TASK_TYPE_111, weaponList, PartnerManager::countWeaponTalent);
        RankActManager.updateOuterTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_111, weaponList, PartnerManager::countWeaponTalent);
        ActConventionManager.updateOuterTask(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_111, weaponList, PartnerManager::countWeaponTalent);
    }
    public static int countWeaponTalent(List<UserWeapon> weaponList, int minTalent) {
        int count = 0;
        for (UserWeapon userWeapon : weaponList) {
            if (userWeapon.getTalent() >= minTalent) {
                count++;
            }
        }
        return count;
    }

    // 重算干员的总资质的任务进度干员总资质达到{0}
    public static void recountMainTaskTalentNum(PBUserData.Builder pbUserData, UserInfo userInfo, List<UserPartner> partnerList) {
        int total = 0;
        for (UserPartner userPartner : partnerList) {
            total += userPartner.takeTotalTalent();
        }
        MainTaskManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_141, total);// 更新主线任务,成就,日常任务的进度
        RankActManager.updateTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_141, total);
    }

    // 是否有未准备的武器,和干员可以装备武器
    public static boolean checkRedPoint(CSGameSystemRedPointResponse.Builder builder, UserInfo userInfo){
        CsGameSystem.RedPoint_Mail.Builder redPointMail = CsGameSystem.RedPoint_Mail.newBuilder();
        List<UserWeapon> weaponList = getUserWeaonList(userInfo.getId());
        boolean isHas = false;
        for (UserWeapon userWeapon : weaponList) {
            if (!isHas && userWeapon.getPartnerId() == 0 && userWeapon.getIsPutOn() == 0) {
                isHas = true;
            }
        }
        if (!isHas) {// 所有武器都已经装备
            return false;
        }

        List<UserPartner> partnerList = getUserPartnerList(userInfo.getId());
        boolean isHas2 = false;
        for (UserPartner userPartner : partnerList) {
            if (!isHas2 && userPartner.getWeaponDbid() == 0) {// 有干员未装备武器
                isHas2 = true;
            }
        }
        if (isHas2) {
            CsGameSystem.RedPoint_Weapon.Builder redPointWeapon = CsGameSystem.RedPoint_Weapon.newBuilder();
            redPointWeapon.setIsCanPutOn(true);
            builder.setWeapon(redPointWeapon);
            return true;
        } else {
            return false;
        }
    }

    // 统计所有武器的生效技能数量
    public static int countTotalAttActiveNum(long userId) {
        List<UserWeapon> weaponList = getUserWeaonList(userId);
        int total = 0;
        for (UserWeapon userWeapon : weaponList) {
            total += userWeapon.countAttActiveNum();
        }
        return total;
    }

    // 生成干员快照列表
    public static String createPartnerPhoto(long userId, UserPower userPower) {
        if (userPower == null) {
            userPower = GameUser.getUserPower(userId);
        }

        JsonArray jsonArray = new JsonArray();
        List<UserPartner> list = getUserPartnerList(userId);
        for (UserPartner userPartner : list) {
            jsonArray.add(userPartner.creatPhoto(userPower));
        }
        return jsonArray.toString();
    }


    //  干员总数量
    public static int countPartnerNum(long userId) {
        long num = EntityManager.getEntityCount(UserPartner.class, userId);
        return (int) num;
    }

    //  统计武器数量
    public static int countWeaponNum(long userId) {
        int weaponNum = (int) EntityManager.getEntityCount(UserWeapon.class, userId);// 当前的武器数量
        return weaponNum;
    }

    public static long getPartnerTotalPower(long userId) {
        List<UserPartner> partnerList = getUserPartnerList(userId);
        long totalPower = 0;
        for (UserPartner userPartner : partnerList) {
            totalPower += userPartner.getTotalPower();
        }
        return totalPower;
    }

    // 批量更新商业建筑的城市收益，并更新userpower
    public static void batchUpdatePartnerPower(PBUserData.Builder pbUserData, UserInfo userInfo, UserPower userPower, List<UserPartner> partnerList) {
        long total = 0;
        for (UserPartner userPartner : partnerList) {
            long addPower = userPartner.reCountPower(userInfo, userPower);
            if (addPower != 0) {
                userPartner.update();
                ProtoDataUtils.updatePBUserData(pbUserData, userPartner);
                total += addPower;
            }
        }
        if (total != 0) {
            long newPower = userPower.getPower() + total;
            userPower.handlePowerChange(pbUserData, userInfo, newPower);
        } else {
            userPower.update();
            ProtoDataUtils.updatePBUserData(pbUserData, userPower);
        }
    }

    // 获取干员Id 列表
    public static JsonArray getParterIds(List<UserPartner> partnerList) {
        JsonArray jsonArray = new JsonArray();
        for (UserPartner userPartner : partnerList) {
            int partnerId = userPartner.getPartnerId();
            if (!Tool.isInList(jsonArray, partnerId)) {
                jsonArray.add(partnerId);
            }
        }
        return jsonArray;
    }

    /**
     * 处理干员技能升级带来的战力变化，和驻派的商业建筑的收益变化
     * @param pbUserData
     * @param userInfo
     * @param userPower
     * @param type 0-基础技能 会影响自身战力，提供总战力，影响商业建筑的收益，1-星级技能，2-大世界技能，远征技能 属于具体模块的技能
     */
    public static void handlePartnerLevelUp(PBUserData.Builder pbUserData,UserInfo userInfo, UserPower userPower, UserPartner userPartner, Skill skill, int newLevel, int type) {
        if (skill == null) {
            return;
        }
        int effectType = skill.getEffectType();
        SkillEffectType skillEffectType = SkillManager.getSkillEffectType(effectType);
        if (skillEffectType == null) {
            return;
        }

        boolean isAddPower = false;// 是否自身增加战力
        boolean isAddEarn = false;// 是否增加城市收益
        if (type == 0) {// 0-基础技能 会影响自身战力，提供总战力，影响商业建筑的收益
            if (effectType == SkillConstant.EFFECT_TYPE_2) {// 加资质   固定值
                isAddPower = true;
            }
            if (effectType == SkillConstant.EFFECT_TYPE_3) {//派遣赚速  百分比加成
                isAddEarn = true;
                MainTaskManager.addTaskProgress(pbUserData, userInfo, MainTaskConstant.TASK_TYPE_32, 1);// 更新主线任务,成就,日常任务的进度
            }
        }
        if (type == 1) {// 1-星级技能 只加资质
            if (effectType == SkillConstant.EFFECT_TYPE_2) {// 加资质   固定值
                isAddPower = true;
            }
        } else if (type == 2) {// 2-大世界技能，远征技能 属于具体模块的技能
            SkillManager.addSkillEffect(pbUserData, userInfo.getId(), skill, newLevel);
        } else if (type == 3) {// 光环技能
            if (effectType == SkillConstant.EFFECT_TYPE_1) {// 光环技能 加自身战力百分比
                isAddPower = true;
            } else if (effectType == SkillConstant.EFFECT_TYPE_45) {// 光环技能 对应性格的干员战力加成 +%
                int addValue = skill.takeLevelUpDiff(newLevel);//  每升1级，增加的加成值
                if (addValue > 0) {
                    JsonArray jsonArray = SkillManager.addSkillEffectArray(skill.getEffectParam(), addValue, userPower.getPowerAddHaloPerArray());
                    userPower.putPowerAddHaloPer(jsonArray.toString());
                    List<UserPartner> partnerList =  userPower.takeUserPartnerList(skill.getEffectParam());
                    PartnerManager.batchUpdatePartnerPower(pbUserData, userInfo, userPower, partnerList);
                }
            }
        }

        if (isAddPower) {// 是否增加战力
            long addPower = userPartner.reCountPower(userInfo, userPower);
            if (addPower > 0) {
                long newPower = userPower.getPower() + addPower;
                userPower.handlePowerChange(pbUserData, userInfo, newPower);
            }
        }
        if (isAddEarn && userPartner.getBuildId() > 0) {// // 是否增加城市收益
            UserBuild userBuild = BuildManager.getUserBuild(userInfo.getId(), userPartner.getBuildId());
            int addValue = skill.takeLevelUpDiff(newLevel);//  每升1级，增加的加成值,增量更新，可能会委派多个干员，不能全量更新
            userBuild.addPartnerAdd2(addValue);
            List<UserBuild> buildList = new ArrayList<>();// 有委派到商业建筑
            buildList.add(userBuild);
            BuildManager.batchUpdateBuildEarn(pbUserData, userInfo, userPower, buildList);
        }
    }

    /**
     * 处理干员提升星数（专属技能升级）带来的变化，技能类型：有可能提升武器上限
     */
    public static void handlePartnerExstuntLevelUp(PBUserData.Builder pbUserData,UserInfo userInfo, UserPower userPower, UserPartner userPartner, int[] skillIds, int newLevel) {
        if (skillIds == null || skillIds.length == 0) {
            return;
        }

        boolean isUpdate = false;
        for (int i=0; i<skillIds.length; i++) {
            Skill skill = SkillManager.getSkill(skillIds[i]);
            if (skill == null) {
                continue;
            }
            int effectType = skill.getEffectType();
            if (effectType == SkillConstant.EFFECT_TYPE_12) {// 提升武器等级上限,这个比较特殊记录在user_power,其他都在user_skill_effect
                int addValue = skill.takeLevelUpDiff(newLevel);//  每升1级，增加的加成值,增量更新，可能会委派多个干员，不能全量更新
                if (addValue > 0) {
                    userPower.addWeaponLevelMaxAdd(addValue);
                    isUpdate = true;
                }
            } else if (Tool.isInList(SkillConstant.SKILL_EFFECT_LIST, effectType)) {
                SkillManager.addSkillEffect(pbUserData, userInfo.getId(), skill, newLevel);
            }
        }

        if (isUpdate) {
            userPower.update();
            ProtoDataUtils.updatePBUserData(pbUserData, userPower);
        }
    }

    // 根据
    public static int getStarLevel(int stage) {
        double aa = Math.floor(stage / Constant.PARTNER_STAR_STAGE);
        return (int) aa;
    }
}